package token

import (
	"fmt"
	"time"

	"github.com/dgrijalva/jwt-go"
)

type BrokerClaims struct {
	jwt.StandardClaims
	Tenant string `json:"tenant"`
	Sign   string `json:"sign"`
	User   string `json:"user"`
}

func Create(claims BrokerClaims, secret string, second int) (string, error) {
	nowTime := time.Now() //当前时间
	expireTime := nowTime.Add(time.Second * time.Duration(second))

	claims.IssuedAt = nowTime.Unix()     //签发时间
	claims.ExpiresAt = expireTime.Unix() //到期时间
	claims.Issuer = "dbrs"               //签发人

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err := token.SignedString([]byte(secret))
	if err != nil {
		return "", err
	}
	return tokenString, nil
}

func Parse(tokenString string, secret string) (*BrokerClaims, error) {
	token, err := jwt.ParseWithClaims(tokenString, &BrokerClaims{}, func(token *jwt.Token) (interface{}, error) {
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
		}
		return []byte(secret), nil
	})
	if err != nil {
		if ve, ok := err.(*jwt.ValidationError); ok {
			if ve.Errors&jwt.ValidationErrorMalformed != 0 {
				return nil, fmt.Errorf("That's not even a token")
			} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
				return nil, fmt.Errorf("Token is expired")
			} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
				return nil, fmt.Errorf("Token not active yet")
			} else {
				return nil, fmt.Errorf("Couldn't handle this token")
			}
		}
	}
	if claims, ok := token.Claims.(*BrokerClaims); ok && token.Valid {
		return claims, nil
	}
	return nil, fmt.Errorf("Couldn't handle this token")
}
